#include "SipSrvInviteTrans.hpp"
#include "SipUserAgent.hpp"

namespace wtsip{

CSipSrvInviteTrans::CSipSrvInviteTrans(SipMessage& request, CSipUserAgent& ua):
CSipSrvTransaction(request, ua), m_invListener(0), m_cancel(0)
{
    m_State = InvSrvInvite;
}

CSipSrvInviteTrans::~CSipSrvInviteTrans(){
    if (m_cancel){
        delete m_cancel;
        m_cancel = NULL;
    }
}


bool CSipSrvInviteTrans::send(std::auto_ptr<SipMessage> msg)
{
    if (!msg.get() || !msg->isResponse())
        return false;

    //CSipSrvInviteTransListener* srvLsn = dynamic_cast<CSipSrvInviteTransListener*>(m_listener);
    int hCode = msg->header(h_StatusLine).responseCode() / 100;
    if (1 == hCode){
        if (InvSrvInvite == m_State || InvSrvTrying == m_State){
            if (InvSrvTrying != m_State){
                setState(InvSrvTrying);
            }
            m_ua.send(msg);
        }
    } else if (2 == hCode){
        if (InvSrvInvite == m_State || InvSrvTrying == m_State || InvSrvSuccessed == m_State)
        {
            if (InvSrvSuccessed != m_State){
                setState(InvSrvSuccessed);
            }
            m_ua.send(msg);
        } else if (InvSrvCancel == m_State || InvSrvCanceled == m_State)
        {
            if (InvSrvCanceled != m_State){
                setState(InvSrvCanceled);
            }
            m_ua.send(msg);
        }
    } else if (4 == hCode){
        if (InvSrvInvite == m_State || InvSrvTrying == m_State 
            || InvSrvCanceled == m_State || InvSrvFailed == m_State)
        {
            if (InvSrvFailed != m_State){
                setState(InvSrvFailed);
            }
            m_ua.send(msg);
        }
    }
    return true;
}


bool CSipSrvInviteTrans::processIncoming(SipMessage* msg)
{
    if (!msg)
        return false;

    assert(msg->isRequest());

    MethodTypes m = msg->header(h_RequestLine).method();
    if (resip::INVITE == m)
    {
        if (InvSrvInitial == m_State){
            setState(InvSrvInvite);
        }
    } else if (resip::CANCEL == m)
    {
        if (InvSrvInvite == m_State || InvSrvTrying == m_State){
            setState(InvSrvCancel);
            if (!m_cancel){
                m_cancel = static_cast<SipMessage*>(msg->clone());
            }
            if (m_invListener){
                m_invListener->onCancel(*this, *msg);
            }
        }
    } else if (resip::ACK == m)
    {
        if (InvSrvFailed == m_State){
            setState(InvSrvTerminated);
            if (m_invListener){
                m_invListener->onFailed(*this, *msg);
            }
        }
    }
    return true;
}


bool CSipSrvInviteTrans::registerInvListener(CSipSrvInviteTransListener* ls){
    m_invListener = ls;
    return true;
}


bool CSipSrvInviteTrans::unregisterInvListener(){
    m_invListener = NULL;
    return true;
}


SipMessage* CSipSrvInviteTrans::createCancelOK(){
    SipMessage* cancelok = NULL;
    if (m_cancel){
        cancelok = m_ua.createResponse(*m_cancel, 200);
    }
    return cancelok;
}


bool CSipSrvInviteTrans::setState(int state){
    m_State = state;
    if (m_invListener){
        m_invListener->onStateChange(*this, state);
    }
    return true;
}


}//namespace

